const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const cosService = require('./cosService');

/**
 * 用户认证与权限管理模块
 * 负责用户身份验证和权限控制
 */
class UserAuthService {
  constructor() {
    // 本地用户信息文件路径
    this.localUserFilePath = path.join(__dirname, '../public/users.json');
    
    // 云端用户信息文件路径
    this.cloudUserFilePath = 'config/users.json';
    
    // 默认超级管理员用户名（系统初始化时使用）
    this.defaultAdmin = 'admin';
    
    // 权限级别定义
    this.roles = {
      ADMIN: 'admin',      // 管理员 - 可以管理所有数据和用户
      EDITOR: 'editor',    // 编辑者 - 可以编辑项目，但不能管理用户
      VIEWER: 'viewer',    // 查看者 - 只能查看和使用项目
      GUEST: 'guest'       // 访客 - 最低权限级别
    };
    
    // 缓存的用户信息
    this.userCache = null;
    
    // 缓存过期时间 (5分钟)
    this.cacheExpiryMs = 5 * 60 * 1000;
    
    // 最后一次缓存更新时间
    this.lastCacheUpdate = 0;
    
    // 初始化
    this.init();
  }
  
  /**
   * 初始化用户系统
   */
  async init() {
    try {
      // 确保用户文件存在
      if (!await this.ensureUserFile()) {
        console.error('[UserAuth] 初始化用户系统失败');
      }
    } catch (error) {
      console.error('[UserAuth] 初始化错误:', error);
    }
  }
  
  /**
   * 确保用户文件存在
   * 如果不存在则创建默认用户文件
   */
  async ensureUserFile() {
    try {
      // 首先检查本地文件
      if (!fs.existsSync(this.localUserFilePath)) {
        console.log('[UserAuth] 本地用户文件不存在，尝试从云端获取');
        
        // 尝试从云端获取
        const cloudData = await cosService.downloadData(this.cloudUserFilePath);
        
        if (cloudData && cloudData.users && cloudData.users.length > 0) {
          // 保存到本地
          fs.writeFileSync(this.localUserFilePath, JSON.stringify(cloudData, null, 2), 'utf8');
          console.log('[UserAuth] 已从云端获取用户数据');
          return true;
        }
        
        // 如果云端也没有，创建默认用户文件
        const defaultData = this.createDefaultUserData();
        fs.writeFileSync(this.localUserFilePath, JSON.stringify(defaultData, null, 2), 'utf8');
        
        // 同步到云端
        await cosService.uploadData(defaultData, this.cloudUserFilePath);
        
        console.log('[UserAuth] 已创建默认用户数据');
      }
      return true;
    } catch (error) {
      console.error('[UserAuth] 确保用户文件存在失败:', error);
      return false;
    }
  }
  
  /**
   * 创建默认用户数据
   */
  createDefaultUserData() {
    // 为默认管理员生成随机密码
    const defaultPassword = Math.random().toString(36).substring(2, 10);
    const passwordHash = this.hashPassword(defaultPassword);
    
    console.log(`[UserAuth] 创建默认管理员账户: ${this.defaultAdmin} / ${defaultPassword}`);
    
    return {
      users: [
        {
          id: crypto.randomUUID(),
          username: this.defaultAdmin,
          passwordHash: passwordHash,
          role: this.roles.ADMIN,
          displayName: '系统管理员',
          email: '',
          createdAt: new Date().toISOString(),
          lastLogin: null
        }
      ],
      _meta: {
        createdAt: new Date().toISOString(),
        version: '1.0.0'
      }
    };
  }
  
  /**
   * 哈希密码
   * @param {string} password 明文密码
   * @returns {string} 密码哈希值
   */
  hashPassword(password) {
    const salt = crypto.randomBytes(16).toString('hex');
    const hash = crypto.pbkdf2Sync(password, salt, 1000, 64, 'sha512').toString('hex');
    return `${salt}:${hash}`;
  }
  
  /**
   * 验证密码
   * @param {string} password 要验证的明文密码
   * @param {string} storedHash 存储的密码哈希
   * @returns {boolean} 密码是否正确
   */
  verifyPassword(password, storedHash) {
    const [salt, hash] = storedHash.split(':');
    const calculatedHash = crypto.pbkdf2Sync(password, salt, 1000, 64, 'sha512').toString('hex');
    return hash === calculatedHash;
  }
  
  /**
   * 获取所有用户信息
   * @param {boolean} forceRefresh 是否强制刷新缓存
   * @returns {Promise<Array>} 用户信息数组
   */
  async getUsers(forceRefresh = false) {
    try {
      const now = Date.now();
      
      // 检查缓存是否有效
      if (
        !forceRefresh &&
        this.userCache &&
        (now - this.lastCacheUpdate) < this.cacheExpiryMs
      ) {
        return this.userCache.users;
      }
      
      // 确保用户文件存在
      await this.ensureUserFile();
      
      // 读取用户文件
      const content = fs.readFileSync(this.localUserFilePath, 'utf8');
      const userData = JSON.parse(content);
      
      // 更新缓存
      this.userCache = userData;
      this.lastCacheUpdate = now;
      
      return userData.users;
    } catch (error) {
      console.error('[UserAuth] 获取用户信息失败:', error);
      return [];
    }
  }
  
  /**
   * 获取单个用户信息
   * @param {string} username 用户名
   * @returns {Promise<Object|null>} 用户信息对象
   */
  async getUserByUsername(username) {
    const users = await this.getUsers();
    return users.find(user => user.username === username) || null;
  }
  
  /**
   * 用户登录验证
   * @param {string} username 用户名
   * @param {string} password 密码
   * @returns {Promise<Object|null>} 登录成功返回用户信息，失败返回null
   */
  async login(username, password) {
    try {
      // 获取用户信息
      const user = await this.getUserByUsername(username);
      
      if (!user) {
        console.warn(`[UserAuth] 登录失败: 用户 ${username} 不存在`);
        return null;
      }
      
      // 验证密码
      if (this.verifyPassword(password, user.passwordHash)) {
        // 更新最后登录时间
        const users = await this.getUsers();
        const userIndex = users.findIndex(u => u.id === user.id);
        
        if (userIndex !== -1) {
          users[userIndex].lastLogin = new Date().toISOString();
          await this.saveUsers(users);
        }
        
        // 返回用户信息(不包含密码哈希)
        const { passwordHash, ...userInfo } = user;
        return userInfo;
      }
      
      console.warn(`[UserAuth] 登录失败: ${username} 密码错误`);
      return null;
    } catch (error) {
      console.error('[UserAuth] 登录验证失败:', error);
      return null;
    }
  }
  
  /**
   * 保存用户信息
   * @param {Array} users 用户信息数组
   * @returns {Promise<boolean>} 是否保存成功
   */
  async saveUsers(users) {
    try {
      // 读取当前用户数据
      const content = fs.readFileSync(this.localUserFilePath, 'utf8');
      const userData = JSON.parse(content);
      
      // 更新用户数组
      userData.users = users;
      
      // 保存到本地文件
      fs.writeFileSync(this.localUserFilePath, JSON.stringify(userData, null, 2), 'utf8');
      
      // 同步到云端
      await cosService.uploadData(userData, this.cloudUserFilePath);
      
      // 清除缓存
      this.userCache = null;
      
      return true;
    } catch (error) {
      console.error('[UserAuth] 保存用户信息失败:', error);
      return false;
    }
  }
  
  /**
   * 创建新用户
   * @param {Object} userData 用户数据
   * @returns {Promise<Object|null>} 创建成功返回用户信息，失败返回null
   */
  async createUser(userData) {
    try {
      // 获取所有用户
      const users = await this.getUsers();
      
      // 检查用户名是否已存在
      if (users.some(user => user.username === userData.username)) {
        console.error(`[UserAuth] 创建用户失败: 用户名 ${userData.username} 已存在`);
        return null;
      }
      
      // 创建用户对象
      const newUser = {
        id: crypto.randomUUID(),
        username: userData.username,
        passwordHash: this.hashPassword(userData.password),
        role: userData.role || this.roles.VIEWER,
        displayName: userData.displayName || userData.username,
        email: userData.email || '',
        createdAt: new Date().toISOString(),
        lastLogin: null
      };
      
      // 添加新用户
      users.push(newUser);
      
      // 保存用户信息
      if (await this.saveUsers(users)) {
        // 返回用户信息(不包含密码哈希)
        const { passwordHash, ...userInfo } = newUser;
        return userInfo;
      }
      
      return null;
    } catch (error) {
      console.error('[UserAuth] 创建用户失败:', error);
      return null;
    }
  }
  
  /**
   * 更新用户信息
   * @param {string} userId 用户ID
   * @param {Object} userData 要更新的用户数据
   * @returns {Promise<Object|null>} 更新成功返回用户信息，失败返回null
   */
  async updateUser(userId, userData) {
    try {
      // 获取所有用户
      const users = await this.getUsers();
      
      // 查找要更新的用户
      const userIndex = users.findIndex(user => user.id === userId);
      
      if (userIndex === -1) {
        console.error(`[UserAuth] 更新用户失败: 用户ID ${userId} 不存在`);
        return null;
      }
      
      // 更新用户信息
      const user = users[userIndex];
      
      if (userData.username && userData.username !== user.username) {
        // 检查新用户名是否已存在
        if (users.some(u => u.username === userData.username && u.id !== userId)) {
          console.error(`[UserAuth] 更新用户失败: 用户名 ${userData.username} 已存在`);
          return null;
        }
        user.username = userData.username;
      }
      
      // 如果提供了新密码，更新密码哈希
      if (userData.password) {
        user.passwordHash = this.hashPassword(userData.password);
      }
      
      // 更新其他字段
      if (userData.role) user.role = userData.role;
      if (userData.displayName) user.displayName = userData.displayName;
      if (userData.email !== undefined) user.email = userData.email;
      
      // 保存用户信息
      if (await this.saveUsers(users)) {
        // 返回用户信息(不包含密码哈希)
        const { passwordHash, ...userInfo } = user;
        return userInfo;
      }
      
      return null;
    } catch (error) {
      console.error('[UserAuth] 更新用户失败:', error);
      return null;
    }
  }
  
  /**
   * 删除用户
   * @param {string} userId 要删除的用户ID
   * @returns {Promise<boolean>} 是否删除成功
   */
  async deleteUser(userId) {
    try {
      // 获取所有用户
      const users = await this.getUsers();
      
      // 确保至少保留一个管理员用户
      const adminUsers = users.filter(user => user.role === this.roles.ADMIN);
      const userToDelete = users.find(user => user.id === userId);
      
      if (!userToDelete) {
        console.error(`[UserAuth] 删除用户失败: 用户ID ${userId} 不存在`);
        return false;
      }
      
      // 如果要删除的是唯一的管理员，阻止操作
      if (userToDelete.role === this.roles.ADMIN && adminUsers.length === 1) {
        console.error('[UserAuth] 删除用户失败: 无法删除唯一的管理员用户');
        return false;
      }
      
      // 过滤掉要删除的用户
      const newUsers = users.filter(user => user.id !== userId);
      
      // 保存更新后的用户信息
      return await this.saveUsers(newUsers);
    } catch (error) {
      console.error('[UserAuth] 删除用户失败:', error);
      return false;
    }
  }
  
  /**
   * 检查用户是否有指定权限
   * @param {string} userId 用户ID
   * @param {string} requiredRole 需要的权限角色
   * @returns {Promise<boolean>} 是否有权限
   */
  async hasPermission(userId, requiredRole) {
    try {
      // 获取所有用户
      const users = await this.getUsers();
      
      // 查找用户
      const user = users.find(user => user.id === userId);
      
      if (!user) {
        return false;
      }
      
      // 管理员拥有所有权限
      if (user.role === this.roles.ADMIN) {
        return true;
      }
      
      // 其他权限判断
      switch (requiredRole) {
        case this.roles.ADMIN:
          return user.role === this.roles.ADMIN;
        case this.roles.EDITOR:
          return [this.roles.ADMIN, this.roles.EDITOR].includes(user.role);
        case this.roles.VIEWER:
          return [this.roles.ADMIN, this.roles.EDITOR, this.roles.VIEWER].includes(user.role);
        case this.roles.GUEST:
          return true; // 所有用户都有访客权限
        default:
          return false;
      }
    } catch (error) {
      console.error('[UserAuth] 检查权限失败:', error);
      return false;
    }
  }
  
  /**
   * 获取当前用户ID (基于MAC地址和设备ID)
   * 与cosService中的方法保持一致
   * @returns {string} 用户ID
   */
  getUserId() {
    return cosService.getUserId();
  }
  
  /**
   * 清除缓存数据
   */
  clearCache() {
    this.userCache = null;
    this.lastCacheUpdate = 0;
  }
}

// 创建单例实例
const userAuthService = new UserAuthService();

module.exports = userAuthService;
